package com.zatech.cgnci.project.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zatech.cgnci.project.base.context.UserContext;
import com.zatech.cgnci.project.base.enums.ApprovalConfigEnum;
import com.zatech.cgnci.project.base.enums.BusinessScenariosEnum;
import com.zatech.cgnci.project.base.enums.OperationTypeEnum;
import com.zatech.cgnci.project.base.enums.ResponseCodeEnum;
import com.zatech.cgnci.project.base.exception.GlobalException;
import com.zatech.cgnci.project.base.utils.BeanUtils;
import com.zatech.cgnci.project.base.utils.ConvertUtils;
import com.zatech.cgnci.project.base.utils.DateUtils;
import com.zatech.cgnci.project.base.utils.VerifyUtils;
import com.zatech.cgnci.project.dto.*;
import com.zatech.cgnci.project.entity.CgnciApprovalInfoDO;
import com.zatech.cgnci.project.entity.CgnciBusinessInsuranceDO;
import com.zatech.cgnci.project.entity.CgnciBusinessProjectDO;
import com.zatech.cgnci.project.entity.UserEntity;
import com.zatech.cgnci.project.mapper.CgnciApprovalInfoMapper;
import com.zatech.cgnci.project.service.*;
import com.zatech.cgnci.project.vo.ApprovalConfigVO;
import com.zatech.cgnci.project.vo.ApprovalInfoVO;
import com.zatech.cgnci.project.vo.ApprovalRecordVO;
import com.zatech.cgnci.project.vo.CgnciBusinessProjectMainVO;
import com.zatech.cgnci.project.vo.CgnciBusinessProjectPageVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 承保管理--项目 前端控制器
 * </p>
 *
 * @author Generator
 * @since 2024-12-17
 */
@RestController
@RequestMapping("/api/business/project")
@RequiredArgsConstructor
@Api(produces = "application/json", tags = "承保管理--项目api接口文档")
public class CgnciBusinessProjectController {

    private final CgnciBusinessProjectService cgnciBusinessProjectService;

    private final CgnciBusinessInsuranceService cgnciBusinessInsuranceService;

    private final IApprovalService approvalService;

    private final CgnciApprovalInfoMapper approvalInfoMapper;

    private final CgnciDirectInsuranceRiskService cgnciDirectInsuranceRiskService;

    private final CgnciDirectInsuranceDetailService cgnciDirectInsuranceDetailService;

    private final CgnciReinsuranceRiskService cgnciReinsuranceRiskService;

    private final CgnciReinsuranceRiskInsuredService cgnciReinsuranceRiskInsuredService;

    private final CgnciOperationLogsService cgnciOperationLogsService;

    @PostMapping("/page")
    @ApiOperation(value = "分页列表查询")
    public IPage<CgnciBusinessProjectPageVO> page(@RequestBody CgnciBusinessProjectQueryDTO queryDTO) {
        // 获取当前登录用户
        UserEntity user = UserContext.getUser();
        if (VerifyUtils.isNotEmpty(queryDTO.getIsInsurance()) && "1".equals(queryDTO.getIsInsurance())) {
            // 查询不是已注销状态的保单
            List<CgnciBusinessInsuranceDO> insuranceList = cgnciBusinessInsuranceService.list(new LambdaQueryWrapper<CgnciBusinessInsuranceDO>()
                    .notIn(CgnciBusinessInsuranceDO::getStatus, "4")
                    .eq(CgnciBusinessInsuranceDO::getBusinessType, "1"));
            Set<Long> projectIds = insuranceList.stream().distinct().map(CgnciBusinessInsuranceDO::getProjectId).collect(Collectors.toSet());
            queryDTO.setProjectIds(projectIds);
        }
        IPage<CgnciBusinessProjectPageVO> page = cgnciBusinessProjectService.pageBusinessProject(queryDTO);
        List<CgnciBusinessProjectPageVO> records = page.getRecords();
        if (VerifyUtils.isNotEmpty(records)) {
            records.forEach(record -> record.setHasEdit("3".equals(record.getStatus()) && user.getNameAndCode().equals(record.getCreateUser())));
        }
        return page;
    }

    @GetMapping("/detail")
    @ApiOperation(value = "详情")
    public CgnciBusinessProjectMainVO detail(@RequestParam(value = "projectId") @NotNull(message = "projectId不能为空") Long projectId) {
        return cgnciBusinessProjectService.detail(projectId);
    }

    @PostMapping("/next/create")
    @ApiOperation(value = "新建项目-新项目保存")
    @Transactional(rollbackFor = Exception.class)
    public Long nextCreate(@RequestBody @Valid CgnciBusinessProjectNextCreateDTO addCreateDTO) {
        // 获取当前登录用户
        UserEntity user = UserContext.getUser();
        CgnciBusinessProjectDO businessMainDO = ConvertUtils.convert(addCreateDTO, CgnciBusinessProjectDO.class);
        // 第一步先插入业务数据,用来绑定工作量formId formNo,并且关联工作台的跳转地址url以及参数
        businessMainDO.setFormNo(BeanUtils.getUUID());
        businessMainDO.setCreateUser(user.getNameAndCode());
        businessMainDO.setUpdateUser(user.getNameAndCode());
        cgnciBusinessProjectService.save(businessMainDO);

        // 创建任务,绑定工作流formId. 并且关联工作台的跳转地址url以及参数
        ApprovalInfoVO approvalInfoVO = approvalService.create(FlowTaskCreateDTO.builder().approvalConfigGroupId(ApprovalConfigEnum.APPROVAL_CONFIG_005.getGroupId()).formId(String.valueOf(businessMainDO.getProjectId())).formNo(businessMainDO.getFormNo())
                .redirectionUrl(ApprovalConfigEnum.APPROVAL_CONFIG_005.getRedirectionUrl()).redirectionParam(String.valueOf(businessMainDO.getProjectId())).redirectionDesc(ApprovalConfigEnum.APPROVAL_CONFIG_005.getRedirectionDesc()).build());
        //插入新建项目操作日志
        CgnciOperationLogsDTO operationLogsDTO = new CgnciOperationLogsDTO();
        operationLogsDTO.setBizNo(String.valueOf(businessMainDO.getProjectId()));
        operationLogsDTO.setBizType(BusinessScenariosEnum.POLICY.getCode());
        operationLogsDTO.setOperationType(OperationTypeEnum.CREATE_PROJECT.getCode());
        operationLogsDTO.setContent("新建项目任务号：" + approvalInfoVO.getTaskId());
        operationLogsDTO.setCreator(user.getNameAndCode());
        cgnciOperationLogsService.saveLog(operationLogsDTO);
        return businessMainDO.getProjectId();
    }

    @PostMapping("/next/copy")
    @ApiOperation(value = "新建项目-复制项目保存")
    @Transactional(rollbackFor = Exception.class)
    public Long nextCopy(@RequestBody @Valid CgnciBusinessProjectNextCopyDTO nextCopyDTO) {
        // 获取当前登录用户
        UserEntity user = UserContext.getUser();
        CgnciBusinessProjectDO businessProject = cgnciBusinessProjectService.nextCopy(nextCopyDTO);

        // 创建任务,绑定工作流formId. 并且关联工作台的跳转地址url以及参数
        ApprovalInfoVO approvalInfoVO = approvalService.create(FlowTaskCreateDTO.builder().approvalConfigGroupId("005").formId(String.valueOf(businessProject.getProjectId())).formNo(businessProject.getFormNo())
                .redirectionUrl("/cgnci/api/business/project/detail").redirectionParam(String.valueOf(businessProject.getProjectId())).redirectionDesc("跳转项目详情").build());
        //插入新建项目操作日志
        CgnciOperationLogsDTO operationLogsDTO = new CgnciOperationLogsDTO();
        operationLogsDTO.setBizNo(String.valueOf(businessProject.getProjectId()));
        operationLogsDTO.setBizType(BusinessScenariosEnum.POLICY.getCode());
        operationLogsDTO.setOperationType(OperationTypeEnum.CREATE_PROJECT.getCode());
        operationLogsDTO.setContent("新建项目任务号：" + approvalInfoVO.getTaskId());
        operationLogsDTO.setCreator(user.getNameAndCode());
        cgnciOperationLogsService.saveLog(operationLogsDTO);
        return businessProject.getProjectId();
    }

    @GetMapping("/cancel/create")
    @ApiOperation(value = "创建作废项目")
    @Transactional(rollbackFor = Exception.class)
    public Long cancelCreate(@RequestParam(value = "projectId") @NotNull(message = "projectId不能为空") Long projectId) {
        // 获取当前登录用户
        UserEntity user = UserContext.getUser();
        CgnciBusinessProjectDO businessProject = cgnciBusinessProjectService.cancel(projectId);

        // 创建任务,绑定工作流formId,formNo 并且关联工作台的跳转地址url以及参数
        ApprovalInfoVO approvalInfoVO = approvalService.create(FlowTaskCreateDTO.builder().approvalConfigGroupId(ApprovalConfigEnum.APPROVAL_CONFIG_006.getGroupId()).formId(String.valueOf(businessProject.getProjectId())).formNo(businessProject.getFormNo())
                .redirectionUrl(ApprovalConfigEnum.APPROVAL_CONFIG_006.getRedirectionUrl()).redirectionParam(String.valueOf(businessProject.getProjectId())).redirectionDesc(ApprovalConfigEnum.APPROVAL_CONFIG_006.getRedirectionDesc()).build());
        //记录操作日志
        cgnciOperationLogsService.insertOperationLogs(
                businessProject.getProjectId() + "",
                BusinessScenariosEnum.POLICY.getCode(),
                OperationTypeEnum.INVALID_PROJECT.getCode(),
                "作废项目任务号：" + approvalInfoVO.getTaskId(), user.getNameAndCode()
        );
        return businessProject.getProjectId();
    }


    @PostMapping("/cancel/submit")
    @ApiOperation(value = "提交作废项目")
    @Transactional(rollbackFor = Exception.class)
    public void cancelSubmit(@RequestBody @Valid CgnciBusinessProjectCancelDTO cancelDTO) {
        CgnciBusinessProjectDO checkBusinessProject = cgnciBusinessProjectService.getById(cancelDTO.getProjectId());
        if (VerifyUtils.isEmpty(checkBusinessProject)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "projectId有误");
        }
        checkBusinessProject.setCancelReason(cancelDTO.getCancelReason());
        cgnciBusinessProjectService.updateById(checkBusinessProject);

        // 提交审核
        cgnciBusinessProjectService.submit(FlowTaskSubmitDTO.builder().approvalInfoId(cancelDTO.getApprovalInfoId())
                .formId(String.valueOf(checkBusinessProject.getProjectId())).build());
    }

    @PostMapping("/saveOrUpdate")
    @ApiOperation(value = "新增或者修改")
    @Transactional(rollbackFor = Exception.class)
    public void saveOrUpdate(@RequestBody @Valid CgnciBusinessProjectSaveOrUpdateDTO updateDTO) {
        CgnciBusinessProjectDO businessProjectDO = cgnciBusinessProjectService.saveOrUpdateBusinessMain(updateDTO);

        // 提交审核
        if (VerifyUtils.isNotEmpty(updateDTO.getFlowTaskType()) && "submit".equals(updateDTO.getFlowTaskType())) {
            // 是否触发倒签
            String groupId = null;
            if (businessProjectDO.getCreateTime().after(DateUtils.getTimeByType(updateDTO.getBusinessProjectUpdateDTO().getStartDate(), "start"))) {
                groupId = ApprovalConfigEnum.APPROVAL_CONFIG_020.getGroupId();
            }
            if (VerifyUtils.isNotEmpty(groupId)) {
                approvalInfoMapper.updateById(CgnciApprovalInfoDO.builder().approvalInfoId(updateDTO.getApprovalInfoId()).approvalConfigGroupId(groupId).build());
            }
            cgnciBusinessProjectService.submit(FlowTaskSubmitDTO.builder().approvalInfoId(updateDTO.getApprovalInfoId())
                    .formId(String.valueOf(businessProjectDO.getProjectId())).build());
        }
    }

    @PostMapping("/approve")
    @ApiOperation(value = "审核流程任务")
    @Transactional(rollbackFor = Exception.class)
    public void approve(@RequestBody @Valid FlowTaskApprovalDTO flowTaskDTO) {
        cgnciBusinessProjectService.approve(flowTaskDTO);
    }

    @GetMapping("/listBackNode")
    @ApiOperation(value = "获取退回流程节点")
    public List<ApprovalConfigVO> listBackNode(@RequestParam(value = "projectId") @NotNull(message = "projectId不能为空") Long projectId) {
        CgnciBusinessProjectDO businessMainDO = cgnciBusinessProjectService.getById(projectId);
        if (VerifyUtils.isEmpty(businessMainDO)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR);
        }
        return approvalService.listBackNode(String.valueOf(businessMainDO.getProjectId()), businessMainDO.getFormNo());
    }

    @PostMapping("/back")
    @ApiOperation(value = "退回流程任务")
    @Transactional(rollbackFor = Exception.class)
    public void back(@RequestBody @Valid FlowTaskBackDTO flowTaskDTO) {
        cgnciBusinessProjectService.back(flowTaskDTO);
    }

    @GetMapping("/signOut")
    @ApiOperation(value = "注销")
    @Transactional(rollbackFor = Exception.class)
    public void signOut(@RequestParam(value = "projectId") @NotNull(message = "projectId不能为空") Long projectId) {
        cgnciBusinessProjectService.signOut(projectId);
    }

    @GetMapping("/log")
    @ApiOperation(value = "获取操作日志")
    public List<ApprovalRecordVO> log(@RequestParam(value = "projectId") @NotNull(message = "projectId不能为空") Long projectId) {
        return cgnciBusinessProjectService.log(projectId);
    }

    @GetMapping("/insuranceRisk/deleteById")
    @Transactional(rollbackFor = Exception.class)
    @ApiOperation(value = "删除直保险种")
    public void deleteInsuranceRiskById(@RequestParam(value = "riskId") Long riskId) {
        cgnciDirectInsuranceRiskService.deleteInsuranceRisk(riskId, "1");
    }

    @GetMapping("/insuranceRisk/deleteByIds")
    @Transactional(rollbackFor = Exception.class)
    @ApiOperation(value = "批量删除直保险种")
    public void deleteInsuranceRiskByIds(@RequestParam(value = "riskIds") String riskIds) {
        List<Long> idList = Arrays.stream(riskIds.split(",")).map(Long::valueOf).collect(Collectors.toList());
        idList.forEach(id -> cgnciDirectInsuranceRiskService.deleteInsuranceRisk(id, "1"));
    }

    @GetMapping("/insuranceDetail/deleteById")
    @Transactional(rollbackFor = Exception.class)
    @ApiOperation(value = "删除直保标的明细")
    public void deleteInsuranceDetailById(@RequestParam(value = "detailId") Long detailId) {
        cgnciDirectInsuranceDetailService.deleteInsuranceDetail(detailId, "1");
    }

    @GetMapping("/insuranceDetail/deleteByIds")
    @Transactional(rollbackFor = Exception.class)
    @ApiOperation(value = "批量删除直保标的明细")
    public void deleteInsuranceDetailByIds(@RequestParam(value = "detailIds") String detailIds) {
        List<Long> idList = Arrays.stream(detailIds.split(",")).map(Long::valueOf).collect(Collectors.toList());
        idList.forEach(id -> cgnciDirectInsuranceDetailService.deleteInsuranceDetail(id, "1"));
    }

    @GetMapping("/reinsuranceRisk/deleteById")
    @Transactional(rollbackFor = Exception.class)
    @ApiOperation(value = "删除分入分出险种")
    public void deleteReinsuranceRiskDetailById(@RequestParam(value = "reinsuranceRiskId") @ApiParam(value = "reinsuranceRiskId") Long reinsuranceRiskId,
                                                @RequestParam(value = "type") @ApiParam(value = "删除模块(1-分入险种,2-分出险种,3-分入方案/再保人险种)") String type) {
        cgnciReinsuranceRiskService.deleteReinsuranceRiskForBusiness(reinsuranceRiskId, type);
    }

    @GetMapping("/reinsuranceRisk/deleteByIds")
    @Transactional(rollbackFor = Exception.class)
    @ApiOperation(value = "批量删除分入分出险种")
    public void deleteReinsuranceRiskDetailByIds(@RequestParam(value = "reinsuranceRiskIds") @ApiParam(value = "reinsuranceRiskIds") String reinsuranceRiskIds,
                                                 @RequestParam(value = "type") @ApiParam(value = "删除模块(1-分入险种,2-分出险种,3-分入方案/再保人险种)") String type) {
        List<Long> idList = Arrays.stream(reinsuranceRiskIds.split(",")).map(Long::valueOf).collect(Collectors.toList());
        idList.forEach(id -> cgnciReinsuranceRiskService.deleteReinsuranceRiskForBusiness(id, type));
    }

    @GetMapping("/reinsuranceRiskInsured/deleteById")
    @Transactional(rollbackFor = Exception.class)
    @ApiOperation(value = "删除分入分出险种标的")
    public void deleteReinsuranceRiskInsuredById(@RequestParam(value = "riskInsuredId") @ApiParam(value = "riskInsuredId") Long riskInsuredId,
                                                 @RequestParam(value = "type") @ApiParam(value = "删除模块(1-分入险种,2-分出险种,3-分入方案/再保人险种)") String type) {
        cgnciReinsuranceRiskInsuredService.deleteReinsuranceRiskInsuredForBusiness(riskInsuredId, type);
    }

    @GetMapping("/reinsuranceRiskInsured/deleteByIds")
    @Transactional(rollbackFor = Exception.class)
    @ApiOperation(value = "批量删除分入分出险种标的")
    public void deleteReinsuranceRiskInsuredByIds(@RequestParam(value = "riskInsuredIds") @ApiParam(value = "riskInsuredIds") String riskInsuredIds,
                                                  @RequestParam(value = "type") @ApiParam(value = "删除模块(1-分入险种,2-分出险种,3-分入方案/再保人险种)") String type) {
        List<Long> idList = Arrays.stream(riskInsuredIds.split(",")).map(Long::valueOf).collect(Collectors.toList());
        idList.forEach(id -> cgnciReinsuranceRiskInsuredService.deleteReinsuranceRiskInsuredForBusiness(id, type));
    }

}

